package com.eimf.saf.common.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.eimf.saf.base.util.BaseCache;
import com.eimf.saf.base.util.StringUtil;
import com.eimf.saf.common.entity.Dict;
import com.eimf.saf.common.filter.I18nIntercept;

/**
 * @author eden
 * @date 2013-11-13 下午5:19:43
 * @Description: 应用缓存
 */
public final class CommonCache
{

    private static Log logger = LogFactory.getLog(I18nIntercept.class);

    /** 国际化资源表。key:国际化主键 val:数据库记录 */
    private static Map<String, Map<String, String>> internationMap = new ConcurrentHashMap<String, Map<String, String>>();

    /** 国际化资源通用化扩展。key:自定义 val:国际化资源表中的列名及值 */
    private static Map<String, Map<String, String>> internationMapEx = new ConcurrentHashMap<String, Map<String, String>>();

    /** 字典表缓存。key:字典类型主键 val:该类型下的所有字典列表 */
    private static Map<String, List<Dict>> dictMap = new ConcurrentHashMap<String, List<Dict>>();

    /**
     * 初始化国际化资源信息到缓存中。
     * 
     * @param internations
     */
    public static void initInternationInfo(final List<Map<Object, Object>> internations)
    {
        synchronized (CommonCache.internationMap)
        {
            CommonCache.internationMap.clear();
            CommonCache.logger.info("初始化国际化资源信息到缓存中");
            final Map<String, Map<String, String>> internationMap = new HashMap<String, Map<String, String>>();
            for (final Map<Object, Object> internation : internations)
            {
                final Map<String, String> temp = new HashMap<String, String>();
                internationMap.put(internation.get("ID") + "", temp);
                for (final Object key : internation.keySet())
                {
                    final Object value = internation.get(key);
                    temp.put(key + "", value != null ? value + "" : null);
                }
            }
            CommonCache.setInternationMap(internationMap);
        }
    }

    public static void initInternationInfoEx(final List<Map<String, String>> internations)
    {
        synchronized (CommonCache.internationMapEx)
        {
            CommonCache.internationMapEx.clear();
            CommonCache.logger.info("初始化扩展的国际化资源信息到缓存中");
            final Map<String, String> temp = new LinkedHashMap<String, String>();
            for (final Map<String, String> internation : internations)
            {
                temp.put(internation.get("CODE"), internation.get("COMM"));
            }
            CommonCache.internationMapEx.put("lng", temp);
        }
    }

    /**
     * 修改国际化资源信息到缓存中,需要进行内存同步。
     * 
     * @param internations
     */
    public static void updInternationInfo(final List<Map<Object, Object>> internations)
    {
        CommonCache.logger.info("初始化国际化资源信息到缓存中");
        final Map<String, Map<String, String>> internationMap = new HashMap<String, Map<String, String>>();
        for (final Map<Object, Object> internation : internations)
        {
            final Map<String, String> temp = new HashMap<String, String>();
            internationMap.put(internation.get("ID") + "", temp);
            for (final Object key : internation.keySet())
            {
                final Object value = internation.get(key);
                temp.put(key + "", value != null ? value + "" : null);
            }
        }
        for (final Map.Entry<String, Map<String, String>> item : internationMap.entrySet())
        {
            CommonCache.setInternationMap(item.getKey(), item.getValue());
        }
    }

    /**
     * 从缓存中取得国际化资源表。<br>
     * 注：获取中的信息不能作修改操作。
     */
    public static Map<String, Map<String, String>> getInternationMap()
    {
        return CommonCache.internationMap;
    }

    public static Map<String, Map<String, String>> getInternationMapEx()
    {
        return CommonCache.internationMapEx;
    }

    /**
     * 将国际化信息重新存入到缓存中。
     * 
     * @param internationMap
     */
    public static void setInternationMap(final Map<String, Map<String, String>> internationMap)
    {
        for (final Map.Entry<String, Map<String, String>> item : internationMap.entrySet())
        {
            CommonCache.internationMap.put(item.getKey(), item.getValue());
        }
    }

    /**
     * 修改指定主键的国际化资源缓存。
     * 
     * @param key
     * @param value
     */
    public static void setInternationMap(final String key, final Map<String, String> value)
    {
        CommonCache.setInnerInternationMap(key, value);
    }

    /**
     * 修改指定主键的国际化资源缓存。
     * 
     * @param key
     * @param value
     */
    private static void setInnerInternationMap(final String key, final Map<String, String> value)
    {
        CommonCache.internationMap.put(key, value);
    }

    /**
     * 查询指定国际化资源KEY的指定语种的信息。<br>
     * 如果指定语种的信息没有找到，将找系统参数定义的默认语言，如果仍然没找到将返回key。
     * 
     * @param key
     * @param lanuage
     * @return
     */
    public static String getInternationInfo(final String key, final String lanuage)
    {
        String result = null;
        final Map<String, String> map = CommonCache.getInternationMap().get(key);
        if (map == null || map.size() == 0)
        {
            result = key;
        } else
        {
            result = map.get(lanuage);
            if (StringUtil.isBlank(result))
            {
                result = map.get(BaseCache.getSystemParm(CommonContant.DEFAULT_LANGUAGE));
            }

            if (StringUtil.isBlank(result))
            {
                result = key;
            }
        }

        return result;
    }

    // /////////////////////////字典表缓存相关操作///////////////////////////////////////////////////
    /**
     * 初始化数据字典到内存中。
     */
    public static void initDict(final List<Dict> dictList)
    {
        CommonCache.logger.info("初始化数据字典到内存中");
        synchronized (CommonCache.dictMap)
        {
            CommonCache.dictMap.clear();

            final Map<String, List<Dict>> dictMap = new HashMap<String, List<Dict>>();
            for (final Dict item : dictList)
            {
                List<Dict> tempList = dictMap.get(item.getDictTypeId());

                if (tempList == null)
                {
                    tempList = new ArrayList<Dict>();
                    dictMap.put(item.getDictTypeId(), tempList);
                }
                tempList.add(item);
            }
            CommonCache.setDictMap(dictMap);
        }
    }

    /**
     * 从缓存中取得字典资源表.<br>
     * 获取的数据不能做修改操作。
     * 
     * @return
     */
    public static Map<String, List<Dict>> getDictMap()
    {
        return CommonCache.dictMap;
    }

    /**
     * 新增字典缓存。
     * 
     * @param dictTypeId
     * @param dict
     */
    public static void addDictMap(final String dictTypeId, final Dict dict)
    {
        List<Dict> list = CommonCache.getDictMap().get(dictTypeId);
        if (list == null)
        {
            list = new ArrayList<Dict>();
        }

        list.add(dict);
        CommonCache.setDictMap(dictTypeId, list);
    }

    /**
     * 更新字典缓存。
     * 
     * @param dict
     */
    public static void setDictMap(final Map<String, List<Dict>> dict)
    {
        for (final Map.Entry<String, List<Dict>> item : dict.entrySet())
        {
            CommonCache.dictMap.put(item.getKey(), item.getValue());
        }
    }

    /**
     * 更新字典缓存。
     * 
     * @param dictTypeId
     * @param dictList
     */
    public static void setDictMap(final String dictTypeId, final List<Dict> dictList)
    {
        CommonCache.setInnerDictMap(dictTypeId, dictList);
    }

    /**
     * 更新字典缓存。
     * 
     * @param dictTypeId
     * @param dictList
     */
    private static void setInnerDictMap(final String dictTypeId, final List<Dict> dictList)
    {
        CommonCache.dictMap.put(dictTypeId, dictList);
    }

    /**
     * 更新字典缓存。
     * 
     * @param dictTypeId
     * @param dict
     */
    public static void setDictMap(final String dictTypeId, final Dict dict)
    {
        List<Dict> list = CommonCache.getDictMap().get(dictTypeId);

        if (list == null)
        {
            list = new ArrayList<Dict>();
        }

        final Iterator<Dict> iterator = list.iterator();
        while (iterator.hasNext())
        {
            final Dict temp = iterator.next();
            if ((dict.getDictId().trim()).equals(temp.getDictId().trim()))
            {
                temp.setDictName(dict.getDictName());
                temp.setSortNo(dict.getSortNo());
                temp.setDictKey(dict.getDictKey());
                temp.setStatus(dict.getStatus());
                temp.setRemark(dict.getRemark());
            }
        }
        CommonCache.setDictMap(dictTypeId, list);
    }

    /**
     * 更新字典缓存。
     * 
     * @param dictTypeId
     * @param dict
     */
    public static void setDictMap(final String dictTypeId, final String dictId, final String dictKey, final int status)
    {
        List<Dict> list = CommonCache.getDictMap().get(dictTypeId);

        if (list == null)
        {
            list = new ArrayList<Dict>();
        }

        final Iterator<Dict> iterator = list.iterator();
        while (iterator.hasNext())
        {
            final Dict temp = iterator.next();
            if ((dictId.trim()).equals(temp.getDictId().trim()))
            {
                temp.setStatus(status);
                temp.setDictKey(dictKey);
            }
        }
        CommonCache.setDictMap(dictTypeId, list);
    }

    /**
     * 清除指定字典类型、指定CODE的字典。
     * 
     * @param dictTypeId
     * @param dictCode
     */
    public static void removeDict(final String dictTypeId, final String dictId)
    {
        List<Dict> list = CommonCache.getDictMap().get(dictTypeId);

        if (list == null)
        {
            list = new ArrayList<Dict>();
        }

        final Iterator<Dict> iterator = list.iterator();
        while (iterator.hasNext())
        {
            final Dict temp = iterator.next();
            if ((dictId.trim()).equals(temp.getDictId().trim()))
            {
                iterator.remove();
            }
        }

        CommonCache.setDictMap(dictTypeId, list);
    }

    /**
     * 将某个类型的数据全部移除。
     * 
     * @param dictTypeId
     */
    public static void removeDictMap(final String dictTypeId)
    {
        CommonCache.removeInnerDictMap(dictTypeId);
    }

    /**
     * 将某个类型的数据全部移除。
     * 
     * @param dictTypeId
     */
    private static void removeInnerDictMap(final String dictTypeId)
    {
        CommonCache.getDictMap().remove(dictTypeId);
    }

    /**
     * 查询指定字典类别的字典名称，自动从request中取得语言代码进行国际化。
     * 
     * @param type
     * @param val
     * @return
     */
    public static String getDictName(final String type, final String val)
    {
        final List<Dict> temp = CommonCache.getDictMap().get(type);
        for (final Dict item : temp)
        {
            if (val.equals(item.getDictId()))
            {
                return I18nIntercept.convertValue(I18nIntercept.getLanguage(), item.getDictName());
            }
        }
        return null;
    }

    /**
     * 查询指定字典类别的字典名称，未国际化。
     * 
     * @param type
     * @param val
     * @return
     */
    public static String getDictNameNoI18n(final String type, final String val)
    {
        final List<Dict> temp = CommonCache.getDictMap().get(type);
        for (final Dict item : temp)
        {
            if (val.equals(item.getDictId()))
            {
                return item.getDictName();
            }
        }
        return null;
    }

    /**
     * 根据字典类型返回字典列表，未国际化.
     * 
     * @param type
     * @return
     */
    public static List<Dict> getDictByType(final String type)
    {
        return CommonCache.getDictMap().get(type);
    }

    /**
     * 根据字典类型返回字典列表,已国际化。
     * 
     * @param dictType
     * @return
     */
    public static List<Dict> getDictListByType(final String dictType)
    {
        final List<Dict> dictList = CommonCache.getDictMap().get(dictType);

        final List<Dict> tempList = new ArrayList<Dict>();
        for (final Dict item : dictList)
        {
            if (item.getStatus() == CommonContant.DICT_STATUS_Y)
            {
                final Dict temp = new Dict();
                BeanUtils.copyProperties(item, temp);
                temp.setDictName(CommonCache.getI18nInfo(item.getDictName()));
                tempList.add(temp);
            }
        }
        return tempList;
    }

    /**
     * 返回指定国际化资源ID的国际化资源信息.
     * 
     * @param name
     * @return
     */
    public static String getI18nInfo(final String name)
    {
        String result = name;
        final String language = I18nIntercept.getLanguage();
        result = I18nIntercept.convertValue(language, name);
        return result;
    }

}
